﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Bing.Service;

namespace Microsoft.Bing
{
    internal class SearchMarshaller
    {
        internal static void MarshalResponse(SearchResponse response, SearchResults results, SearchMedia media, bool computeWeight, ref uint resultCount)
        {
            results.Clear();
            resultCount = 0;
            if (response == null) return;

            if (media == SearchMedia.Web && null != response.Web)
            {
                resultCount = response.Web.Total;

                WebResult[] webResults = response.Web.Results;
                if (webResults != null)
                {
                    for (int index = 0; index < webResults.Length; index++)
                    {
                        WebResult webResult = webResults[index];

                        SearchResult result = new SearchResult();
                        result.Title = webResult.Title;
                        result.Url = webResult.Url;
                        result.Snippet = webResult.Description;

                        DateTime date;

                        if (DateTime.TryParse(webResult.DateTime, out date))
                        {
                            result.Date = date;
                        }

                        result.DisplayUrl = webResult.DisplayUrl;
                        result.MediaType = MediaTypes.Html;
                        result.Kind = SearchResultKind.Web;
                        result.CacheUrl = webResult.CacheUrl;
                        
                        result.IconUrl = SearchResult.TYPE_WEB_IMAGE;
                        result.LargeIconUrl = SearchResult.TYPE_WEB_LARGE;

                        //Super Ghetto Relevancy
                        if (computeWeight)
                        {
                            result.Relevancy = webResults.Length - index;
                            ComputeRelevancyWeight(response, result);
                        }

                        results.Add(result);
                    }
                }
            }
            else if (media == SearchMedia.Images && null != response.Image)
            {
                resultCount = response.Image.Total;

                ImageResult[] imageResults = response.Image.Results;
                if (imageResults != null)
                {
                    for (int index = 0; index < imageResults.Length; index++)
                    {
                        ImageResult imageResult = imageResults[index];

                        SearchResult result = new SearchResult();
                        result.Title = imageResult.Title;
                        result.Url = imageResult.Url;
                        result.Snippet = String.Empty;
                        result.Date = DateTime.Now;
                        result.DisplayUrl = imageResult.MediaUrl;
                        result.MediaType = MediaTypes.GenericImage;
                        result.Kind = SearchResultKind.Image;
                        result.CacheUrl = imageResult.DisplayUrl;
                        result.Thumbnail = imageResult.Thumbnail;

                        if (imageResult.Thumbnail != null && !String.IsNullOrEmpty(imageResult.Thumbnail.Url))
                        {
                            result.IconUrl = result.LargeIconUrl = imageResult.Thumbnail.Url;
                        }

                        //Check for Silverlight Images
                        InspectMediaType(result);

                        //Super Ghetto Relevancy
                        result.Relevancy = imageResults.Length - index;
                        ComputeRelevancyWeight(response, result);

                        results.Add(result);
                    }
                }
            }
            else if (media == SearchMedia.Video && null != response.Video)
            {
                resultCount = response.Video.Total;

                VideoResult[] videoResults = response.Video.Results;
                if (videoResults != null)
                {
                    for (int index = 0; index < videoResults.Length; index++)
                    {
                        VideoResult videoResult = videoResults[index];

                        SearchResult result = new SearchResult();
                        result.Title = videoResult.Title;
                        result.Url = videoResult.PlayUrl;

                        if (videoResult.RunTimeSpecified)
                            result.Snippet = String.Format(DataResources.FMT_VIDEO_SNIPPET_RUNLENGTH, videoResult.SourceTitle, videoResult.RunTime / 60 / 60);
                        else
                            result.Snippet = String.Format(DataResources.FMT_VIDEO_SNIPPET_NORUNLENGTH, videoResult.SourceTitle);

                        result.Date = DateTime.Now;
                        result.DisplayUrl = videoResult.PlayUrl;
                        result.MediaType = MediaTypes.Video;
                        result.Kind = SearchResultKind.Video;
                        result.Thumbnail = videoResult.StaticThumbnail;

                        result.IconUrl = SearchResult.TYPE_VIDEO_IMAGE;
                        result.LargeIconUrl = SearchResult.TYPE_VIDEO_LARGE;

                        if (videoResult.StaticThumbnail != null)
                        {
                            result.IconUrl = result.LargeIconUrl = videoResult.StaticThumbnail.Url;
                        }

                        //Check for Silverlight Images
                        InspectMediaType(result);

                        //Super Ghetto Relevancy
                        result.Relevancy = videoResults.Length - index;
                        ComputeRelevancyWeight(response, result);

                        //DEBUG: Uncomment to assist in examining arrangements by Relevancy and Date
                        //result.Title = String.Format("R:{0:0.0}, D:{1:d} ", result.Relevancy, result.Date) + videoResult.Title;

                        results.Add(result);
                    }
                }
            }
            else if (media == SearchMedia.News && null != response.News)
            {
                resultCount = response.News.Total;

                NewsResult[] newsResults = response.News.Results;

                if (newsResults != null)
                {
                    for (int index = 0; index < newsResults.Length; index++)
                    {
                        NewsResult newsResult = newsResults[index];

                        SearchResult result = new SearchResult();
                        result.Title = newsResult.Title;
                        result.Url = newsResult.Url;
                        result.Snippet = newsResult.Snippet;
                        result.Date = DateTime.Now;
                        result.DisplayUrl = newsResult.Url;
                        result.MediaType = MediaTypes.NewsArticle;
                        result.Kind = SearchResultKind.News;

                        result.IconUrl = SearchResult.TYPE_NEWS_IMAGE;
                        result.LargeIconUrl = SearchResult.TYPE_NEWS_LARGE;

                        //Check for Silverlight Images
                        InspectMediaType(result);

                        //Super Ghetto Relevancy
                        result.Relevancy = newsResults.Length - index;
                        ComputeRelevancyWeight(response, result);

                        results.Add(result);
                    }
                }
            }
            else if (media == SearchMedia.Phonebook && null != response.Phonebook)
            {
                resultCount = response.Phonebook.Total;

                PhonebookResult[] bookResults = response.Phonebook.Results;
                if (bookResults != null)
                {
                    for (int index = 0; index < bookResults.Length; index++)
                    {
                        PhonebookResult bookResult = bookResults[index];

                        SearchResult result = new SearchResult();
                        result.Title = bookResult.Title;
                        result.Url = bookResult.Url;
                        result.Snippet = FormatPhonebookSnippet(bookResult);
                        result.Date = DateTime.Now;
                        result.DisplayUrl = bookResult.DisplayUrl;
                        result.MediaType = MediaTypes.Phonebook;
                        result.Kind = SearchResultKind.Phonebook;

                        result.IconUrl = SearchResult.TYPE_PHONEBOOK_IMAGE;
                        result.LargeIconUrl = SearchResult.TYPE_PHONEBOOK_LARGE;

                        //Check for Silverlight Images
                        InspectMediaType(result);

                        //Super Ghetto Relevancy
                        result.Relevancy = bookResults.Length - index;
                        ComputeRelevancyWeight(response, result);

                        results.Add(result);
                    }
                }
            }
        }

        internal static  void ComputeRelevancyWeight(SearchResponse searchResponse, SearchResult result)
        {
            if (searchResponse != null && searchResponse.Query != null &&
                !String.IsNullOrEmpty(searchResponse.Query.SearchTerms))
            {
                string terms = searchResponse.Query.SearchTerms.ToUpper();
                string title = result.Title.ToUpper();

                string[] tokens = terms.Split(' ');

                if (tokens != null && tokens.Length > 0)
                {
                    for (int index = 0; index < tokens.Length; index++)
                    {
                        if (title.StartsWith(tokens[index]))
                        {
                            result.Relevancy *= 1.75;
                        }
                        else if (title.Contains(tokens[index]))
                        {
                            result.Relevancy *= 1.5;
                        }
                    }
                }
            }
        }

        internal static void InspectMediaType(SearchResult result)
        {
            if (result.Kind == SearchResultKind.Image)
            {
                if (String.Compare(System.IO.Path.GetExtension(result.DisplayUrl), ".JPG", StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    result.MediaType = MediaTypes.Jpeg;
                    if (String.IsNullOrEmpty(result.IconUrl)) result.IconUrl = SearchResult.TYPE_JPG_IMAGE;
                    if (String.IsNullOrEmpty(result.LargeIconUrl)) result.IconUrl = SearchResult.TYPE_JPG_LARGE;
                }
                else if (String.Compare(System.IO.Path.GetExtension(result.DisplayUrl), ".PNG", StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    result.MediaType = MediaTypes.Png;
                    if (String.IsNullOrEmpty(result.IconUrl)) result.IconUrl = SearchResult.TYPE_PNG_IMAGE;
                    if (String.IsNullOrEmpty(result.LargeIconUrl)) result.IconUrl = SearchResult.TYPE_PNG_LARGE;
                }
            }
            else if (result.Kind == SearchResultKind.Video)
            {
                if (String.Compare(System.IO.Path.GetExtension(result.DisplayUrl), ".WMV", StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    result.MediaType = MediaTypes.WindowsMedia;
                    if (String.IsNullOrEmpty(result.IconUrl)) result.IconUrl = SearchResult.TYPE_VIDEO_IMAGE;
                    if (String.IsNullOrEmpty(result.LargeIconUrl)) result.IconUrl = SearchResult.TYPE_VIDEO_LARGE;
                }
            }
        }

        private static string FormatPhonebookSnippet(PhonebookResult bookResult)
        {
            string text = String.Empty;

            if (!String.IsNullOrEmpty(bookResult.Address))
            {
                text += String.Format("Address: {0}", bookResult.Address);
            }

            if (!String.IsNullOrEmpty(bookResult.City))
            {
                if (text.Length > 0) text += " ";
                text += String.Format("{0}", bookResult.City);
            }

            if (!String.IsNullOrEmpty(bookResult.StateOrProvince))
            {
                if (text.Length > 0) text += ", ";
                text += String.Format("{0}", bookResult.StateOrProvince);
            }

            if (!String.IsNullOrEmpty(bookResult.PostalCode))
            {
                if (text.Length > 0) text += " ";
                text += String.Format("{0}", bookResult.PostalCode);
            }

            if (!String.IsNullOrEmpty(bookResult.CountryOrRegion))
            {
                if (text.Length > 0) text += " ";
                text += String.Format("{0}", bookResult.CountryOrRegion);
            }

            if (!String.IsNullOrEmpty(bookResult.PhoneNumber))
            {
                if (text.Length > 0) text += ", ";
                text += String.Format("Phone: {0}", bookResult.PhoneNumber);
            }

            return text;
        }
    }
}
